package com.brillilab.service.logic.space;

import com.brillilab.common.constant.ResultEnum;
import com.brillilab.common.exceptions.BrillilabException;
import com.brillilab.domain.enums.space.DeviceType;
import com.brillilab.domain.enums.space.SpaceTypeEnum;
import com.brillilab.domain.po.lab.LabDevice;
import com.brillilab.domain.po.space.Device;
import com.brillilab.domain.po.space.Room;
import com.brillilab.domain.vo.space.PositionInfo;
import com.brillilab.domain.vo.space.RoomAdd;
import com.brillilab.service.core.inventory.IReagentInventoryService;
import com.brillilab.service.core.lab.ILabDeviceService;
import com.brillilab.service.core.space.*;
import io.netty.util.concurrent.MultithreadEventExecutorGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wuzhiyu
 * @Title: Room
 * @ProjectName brill_lab
 * @Description: TODO
 * @date 2018/11/139:53
 */
@Service
@Transactional
public class RoomLogic {
    @Autowired
    private IRoomService roomService;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IPanelService panelService;
    @Autowired
    private IBoxService boxService;
    @Autowired
    private IReagentInventoryService reagentInventoryService;
    @Autowired
    private ILabDeviceService labDeviceService;
    @Autowired
    private IKitBoxService kitBoxService;

    /**
     * @return java.lang.Long
     * @Description: 新增房间及占位设备
     * @Params: [roomAdd, labId]
     * @author wuzhiyu
     * @date 2018/11/15 9:24
     */
    public Long addRoom(RoomAdd roomAdd, Long labId) {

        Room room = new Room();
        room.setLabId(labId);
        room.setIsDelete(0);
        room.setName(roomAdd.getName());
        room.setLength(roomAdd.getLength());
        room.setWidth(roomAdd.getWidth());
        roomService.add(room);
        List<Device> deviceList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(roomAdd.getDoorList())) {
            roomAdd.getDoorList().forEach(item -> {
                Device device = new Device();
                device.setLabId(labId);
                device.setDeviceType(DeviceType.DOOR.getCode());
                device.setRoomId(room.getId());
                device.setWidth(item.getWidth());
                device.setHeight(item.getHeight());
                device.setX(item.getX());
                device.setY(item.getY());
                deviceList.add(device);
            });
        }
        if (!CollectionUtils.isEmpty(roomAdd.getBlackList())) {
            roomAdd.getBlackList().forEach(item -> {
                Device device = new Device();
                device.setLabId(labId);
                device.setDeviceType(DeviceType.BLACK_OUT.getCode());
                device.setRoomId(room.getId());
                device.setWidth(item.getWidth());
                device.setHeight(item.getHeight());
                device.setX(item.getX());
                device.setY(item.getY());
                deviceList.add(device);
            });
        }
        if (!CollectionUtils.isEmpty(roomAdd.getMachineList())) {
            List<LabDevice> aioList = labDeviceService.selectList(labId,null);
            if (CollectionUtils.isEmpty(aioList)) {
                throw new BrillilabException(ResultEnum.DATA_NOT_EXIST);
            }
            List<LabDevice> canUseList = aioList.stream().filter(o -> o.getState() == 0).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(canUseList)) {
                throw new BrillilabException(ResultEnum.NO_MORE_DEVICE);
            }
            List<String> noList = canUseList.stream().map(LabDevice::getDeviceNo).distinct().collect(Collectors.toList());
            if (roomAdd.getMachineList().stream().allMatch(p -> noList.contains(p.getRemark()))) {
                roomAdd.getMachineList().forEach(m -> {
                    Device device = new Device();
                    device.setLabId(labId);
                    device.setDeviceType(DeviceType.MACHINE.getCode());
                    device.setRoomId(room.getId());
                    device.setWidth(m.getWidth());
                    device.setHeight(m.getHeight());
                    device.setX(m.getX());
                    device.setY(m.getY());
                    device.setRemark(m.getRemark());
                    device.setAioDeviceId(m.getAioDeviceId());
                    Assert.notNull(m.getAioDeviceId(),"参数缺失");
                    Device newDev = deviceService.add(device);
                    labDeviceService.bindDevice(labId, m.getRemark(), newDev.getId());
                });
            } else {
                throw new BrillilabException(ResultEnum.DATA_NOT_EXIST);
            }
        }
        if (deviceList.size() > 0) {
            deviceService.insertNotUserDeivce(deviceList);
        }
        return room.getId();
    }

    /**
     * @return boolean
     * @Description: 删除room及以下所有空间，有试剂则无法删除
     * @Params: [roomId]
     * @author wuzhiyu
     * @date 2018/11/15 9:23
     */
    public boolean delete(Long roomId) {

        if (reagentInventoryService.InventoryCountInSpace(roomId, SpaceTypeEnum.ROOM) > 0) {
            throw new BrillilabException(ResultEnum.DATA_EXIST_CANT_DELETE);
        }
        List<Device> aioList = deviceService.getAioDevice(roomId);
        if(!CollectionUtils.isEmpty(aioList)){
            aioList.forEach(aio->{
                List<Long> roomIdList = deviceService.getAioBindRoomIdList(aio.getAioDeviceId());
                    if(roomIdList.size()==1&&roomIdList.get(0).equals(aio.getRoomId())){
                        LabDevice device = new LabDevice();
                        device.setState(0);
                        device.setId(aio.getAioDeviceId());
                        labDeviceService.updateById(device);
                    }
            });
        }
        roomService.delete(roomId);
        deviceService.deleteByRoomId(roomId);
        panelService.delete(roomId, SpaceTypeEnum.ROOM);
        boxService.delete(roomId, SpaceTypeEnum.ROOM);
        kitBoxService.delete(roomId, SpaceTypeEnum.ROOM);
        panelService.deletePanelGridUsedByRoomId(roomId);
        return true;
    }

    public boolean update(Long roomId, String name) {
        roomService.update(roomId, name);
        deviceService.updateRoomName(roomId, name);
        panelService.updateRoomName(roomId, name);
        boxService.updateRoomName(roomId, name);
        kitBoxService.updateRoomName(roomId, name);
        reagentInventoryService.updateRoomName(roomId,name);
        return true;
    }
}
